#include "main.h"
#include "splash.cpp"
#include "mainmenu.cpp"
#include "credits.cpp"
#include "level.cpp"
#include "buttonlistener.cpp"
#include "collision.cpp"
#include "mclib.cpp"

PSP_MODULE_INFO("Evil Monkey", 0, 0, 1);
PSP_MAIN_THREAD_ATTR(0);



int exit_callback(int arg1, int arg2, void *common)
{
        sceKernelExitGame();
	return 0;
}

int CallbackThread(SceSize args, void *argp)
{
          int cbid = sceKernelCreateCallback("ExitCallback", exit_callback, NULL);
          sceKernelRegisterExitCallback(cbid);

          sceKernelSleepThreadCB();

          return 0;
}

int SetupCallbacks(void)
{
        bln = sceKernelCreateThread("buttonlistener", buttonListener, 0x11, 256*1024, PSP_THREAD_ATTR_USER, NULL);
        sceKernelStartThread(bln, 0, NULL);

        int thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
        if(thid >= 0)
                sceKernelStartThread(thid, 0, 0);

        return thid;
}

void InitGU()
{
    sceGuInit();
    sceGuStart(GU_DIRECT, dList);

    //BUFFERS
    sceGuDrawBuffer(GU_PSM_8888, fbp0, BUF_WIDTH);
    sceGuDispBuffer(SCR_WIDTH, SCR_HEIGHT, (void*)0x88000, BUF_WIDTH);
    sceGuDepthBuffer((void*)0x110000, BUF_WIDTH);
    sceGuOffset(2048 - (SCR_WIDTH/2), 2048 - (SCR_HEIGHT/2));
    sceGuViewport(2048, 2048, SCR_WIDTH, SCR_HEIGHT);
    sceGuDepthRange(65535, 0);
    
    //SETTINGS
    sceGuScissor(0, 0, SCR_WIDTH, SCR_HEIGHT);
    sceGuEnable(GU_SCISSOR_TEST);
    sceGuDepthFunc(GU_GEQUAL);
    sceGuEnable(GU_DEPTH_TEST);
    sceGuFrontFace(GU_CW);
    sceGuShadeModel(GU_SMOOTH);
    sceGuEnable(GU_CULL_FACE);

    //TEXTURES
    sceGuEnable(GU_TEXTURE_2D);
    sceGuTexMode(GU_PSM_8888, 0, 0, mcnet.Swizzled());
    sceGuTexFunc(GU_TFX_DECAL, GU_TCC_RGB);
    sceGuTexFilter(GU_LINEAR, GU_LINEAR);
    sceGuTexScale(1.0f, 1.0f);
    sceGuTexOffset(0.0f, 0.0f);

    sceGuFinish();
    sceGuSync(0,0);

    sceDisplayWaitVblankStart();
    sceGuDisplay(GU_TRUE);
}

void SetupProjection(void)
{
    sceGumMatrixMode(GU_PROJECTION);
    sceGumLoadIdentity();
    sceGumPerspective(60, 1, 1, 200);

    sceGumMatrixMode(GU_VIEW);
    sceGumLoadIdentity();

    sceGuClearColor(0xFF5C9400);
    sceGuClearDepth(0);
}

void DrawScene(void)
{
    sceGuStart(GU_DIRECT, dList);
    sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);
    sceGumMatrixMode(GU_MODEL);
    sceGumLoadIdentity();

    c_at.x = Monkey.Cam.x; c_at.y = yy; c_at.z = 0;
    c_up.x = 0; c_up.y = 1; c_up.z = 0;

    sceGumLookAt(&Monkey.Cam, &c_at, &c_up);

    //STEPS
    if(step == 1)
        mcShowSplashes();
    else if(step == 2)
    {
        if(splashloaded)
        {
            //splash2.FreeImage();
            //mcnet.FreeImage();
            //splashloaded = 0;
        }
        mcShowMenu();
    } else if(step == 3)
        mcShowCredits();
    else if(step == 5)
    {
        WaitSplash();
        ShowLevel();
    }

    sceGuFinish();
    sceGuSync(0,0);
    
    if(step == 5 && !waitsplash && !waitgameover && showbar)
        mcShowBar();
}

int main(int argc, char** argv) {

    pspDebugScreenInit();
    pspDebugScreenSetBackColor(0xFF5C9400);
    SetupCallbacks();

    mcLoadSplashTex();
    sceRtcGetCurrentTick(&fpsTickLast);
    tickResolution = sceRtcGetTickResolution();

    dList = memalign(16, 640);
    fbp0 = 0;

    InitGU();
    SetupProjection();
    
    Monkey.Level = 1;
    Monkey.Cam.x = xx;
    Monkey.Cam.y = yy;
    Monkey.Cam.z = 3;
    
    LoadTextures();

    while(run)
    {
        Timing.reset();
        DrawScene();
        
        fbp0 = sceGuSwapBuffers();
        dt = Timing.getDeltaSeconds();
        sceGuSync(0,0);
    }

    sceKernelTerminateDeleteThread(bln);

    sceGuTerm();

    free(dList);
    free(fbp0);

    sceKernelExitGame();
    return 0;
}